package com.hundsun.cprs.yyt.service.match.domain;

import java.math.BigDecimal;
import java.util.Date;

import com.hundsun.cprs.yyt.service.match.dto.EntrustRequest;
import com.hundsun.cprs.yyt.service.trade.enums.EnumEntustTag;

/**
 * 
 * 委买委卖订单
 * 
 * @author yangyh
 * 
 */
public class TradeEntrust extends DomainBase implements Cloneable {

    private static final long serialVersionUID = -8202067168575176962L;
    
    public static final Integer EntrustTagNew = EnumEntustTag.NEW_USER.getCode(); //新用户委托单
    
    public static final Integer EntrustTagOld = EnumEntustTag.OLD_USER.getCode(); //老用户委托单

    public static final Integer EntrustStatusCommited = 2;// 已上报

    public static final Integer EntrustStatusPartCanceled = 5;// 部分撤销

    public static final Integer EntrustStatusCanceled = 6;// 撤销

    public static final Integer EntrustStatusPartDealt = 7;// 部分交易

    public static final Integer EntrustStatusDealt = 8;// 已经交易

    public static final Integer EntrustStatusDisused = 9;// 废单

    private Long id;

    private Long goodsId;
    
    private String orderSn;

    private Long entrustNO;// 委托单号

    private String stockAccount;// 交易帐号

    private String fundAccount;// 资金帐号

    private String stockCode;// 合约代码

    private String entrustBS;// 买卖方向

    private Long entrustPrice;// 委托价格,以分为单位

    private Long entrustAmount;// 委托数量
    
    private Integer entrustTag; // 委托单的标签

    private Integer entrustStatus;
    
    private Integer status;

    private String entrustProp;

    private Long defaultFund;// 初始冻结资金

    private Long defaultAmount;// 初始冻结份额

    private Long businessAmount;// 总成交份额(卖为负,买为正)

    private Long totalBusinessFund;// 总的资金支出或收入(卖为正数，买为负数)

    private Long businessFund;// 总交易金额(不包括佣金, 卖为正数，买为负数)
    
    private Long gainBusinessFund; // 总盈利金额(买为0,卖为[匹配价格-委卖价格]*N - 手续费)

    private Long commissionFund;// 总扣除佣金

    private BigDecimal commissionrate;// 佣金比例

    private Long minCommission;// 最小佣金
    
    private Long managementFund;// 综合管理费
    
    private Integer managementRate; // 综合管理费比例

    private Long matchingSeq = 0L;// 最后一次撮合的序列值

    private Date entrustTime;// 委托时间
    
    private Date expireDate;// 过期时间(到期自动撤销)

    private int transactions = 0;// 成交笔数

    private Date lastMatchTime;// 最后一次撮合时间

    private Date gmtCreate;

    private Date gmtModify;

    /**
     * 交易商名称
     */
    private String userName;
    
    private Long userId;

    /**
     * 摘单编号(对应请求委托号)
     */
    private Long deListingNo;

    private Long amount;// 本次成交份额数量

    private Long oldAutoEntrustNO = 0L;

    /**
     * 国际化语言
     */
    private String locale;

    /**
     * 是否有可摘最优单
     */
    private Boolean isBestEntrust;

    public TradeEntrust() {
        super();
    }
    
	public TradeEntrust(EntrustRequest request) {
		super();
		this.setStockAccount(request.getStockAccount());
		this.setFundAccount(request.getFundAccount());
		this.setStockCode(request.getStockCode());
		this.setEntrustBS(request.getEntrustBS());
		this.setEntrustPrice(request.getEntrustPrice());
		this.setEntrustAmount(request.getEntrustAmount());
		this.setEntrustProp(request.getEntrustProp());
		this.setEntrustTime(request.getEntrustTime());
		this.setDefaultFund(0L);
		this.setDefaultAmount(0L);
		this.setBusinessFund(0L);
		this.setBusinessAmount(0L);
		this.setTotalBusinessFund(0L);
		this.setCommissionFund(0L);
		this.setCommissionrate(BigDecimal.ZERO);
		this.setMinCommission(BigDecimal.ZERO.longValue());
		this.setEntrustTag(TradeEntrust.EntrustTagNew);
		this.setManagementFund(BigDecimal.ZERO.longValue());
		this.setManagementRate(0);
		this.setUserName(request.getUserName());
		this.setDeListingNo(request.getEntrustNo());
	}

    /**
     * 是否已上报
     * 
     * @return
     */
    public boolean isStatusCommited() {
        return this.entrustStatus != null && this.entrustStatus.equals(EntrustStatusCommited);
    }

    /**
     * 是否部分撤销
     * 
     * @return
     */
    public boolean isStatusPartCanceled() {
        return this.entrustStatus != null && this.entrustStatus.equals(EntrustStatusPartCanceled);
    }

    /**
     * 是否撤销
     * 
     * @return
     */
    public boolean isStatusCanceled() {
        return this.entrustStatus != null && this.entrustStatus.equals(EntrustStatusCanceled);
    }

    /**
     * 是否部分交易
     * 
     * @return
     */
    public boolean isStatusPartDealt() {
        return this.entrustStatus != null && this.entrustStatus.equals(EntrustStatusPartDealt);
    }

    /**
     * 是否已经交易
     * 
     * @return
     */
    public boolean isStatusDealt() {
        return this.entrustStatus != null && this.entrustStatus.equals(EntrustStatusDealt);
    }

    /**
     * 是否废单
     * 
     * @return
     */
    public boolean isStatusDisused() {
        return this.entrustStatus != null && this.entrustStatus.equals(EntrustStatusDisused);
    }

    /**
     * 是否委买
     * 
     * @return
     */
    public boolean isBuy() {
        return this.entrustBS != null && this.entrustBS.equals(EntrustRequest.EntrustBuy);
    }

    /**
     * 是否委卖
     * 
     * @return
     */
    public boolean isSell() {
        return this.entrustBS != null && this.entrustBS.equals(EntrustRequest.EntrustSell);
    }

    /**
     * 是否最优五档即时成交剩余撤销
     * 
     * @return
     */
    public boolean isPropBestFiveLastCancel() {
        return this.entrustProp != null
                && this.entrustProp
                        .equalsIgnoreCase(EntrustRequest.EntrustPropBestFiveLastCancel);
    }

    /**
     * 不成交是否需要撤单
     * 
     * @return
     */
    public boolean isLastEntrustCancel() {
        return isPropBestFiveLastCancel();// 目前只有最优五档即时成交剩余撤销是不成交则撤单
    }

    /**
     * 不成交是否需要挂单
     * 
     * @return
     */
    public boolean isLastEntrustPaste() {
        //return !isLastEntrustCancel();
        return true;
    }
   
    
    /**
     * 撮合成功,减去撮合成功的委托量
     * 
     * @param n
     * @return 如果成功扣除,返回true,否则返回false
     */
    public boolean subEntrustAmount(long n) {
        this.amount = n;
        long left = this.getSurplusEntrustAmount() - Math.abs(n);
        if (left < 0) {
            return false;
        }
        addBusinessAmount(n);
        return true;
    }

    /**
     * 是否委托的数量已经全部成交
     * 
     * @return
     */
    public boolean isEntrustAmountAllMatch() {
        return this.getSurplusEntrustAmount() == 0;
    }

    /**
     * 得到剩余未撮合的份额数量
     * 
     * @return
     */
    public long getSurplusEntrustAmount() {
        return this.entrustAmount - Math.abs(this.businessAmount);
    }

    /**
     * 增加成交份额数
     */
    public void addBusinessAmount(long n) {
        if (this.isBuy()) {
            this.businessAmount += Math.abs(n);
        } else {
            this.businessAmount -= Math.abs(n);
        }

    }

    /**
     * 增加总交易额
     * 
     * @param n
     */
    public void addBusinessFund(long n) {
        if (this.isBuy()) {
            this.businessFund -= Math.abs(n);
            this.totalBusinessFund -= Math.abs(n);
        } else {
            this.businessFund += Math.abs(n);
            this.totalBusinessFund += Math.abs(n);
        }
    }

    /**
     * 增加总佣金
     * 
     * @param n
     */
    public void addCommissionFund(long n) {
        this.commissionFund += Math.abs(n);
        this.totalBusinessFund -= Math.abs(n);
    }
    
    /**
     * 增加总综合管理费
     * @param n
     */
    public void addManagementFund(long n) {
        this.managementFund += Math.abs(n);
        this.totalBusinessFund -= Math.abs(n);
    }
    
    public void calculateGainBusinessFund(){
        if (this.isSell()) {
            this.gainBusinessFund = this.totalBusinessFund - this.entrustPrice * Math.abs(this.businessAmount);
        } else {
            this.gainBusinessFund = 0l;
        }
    }

    /**
     * 增加一笔成交
     */
    public void addTransactions() {
        this.transactions++;
    }

    /**
     * 是否冻结资金已经全部成交
     * 
     * @return
     */
    public boolean isFreezeFundLeft() {
        return getSurplusFreezeFund() > 0;
    }

    /**
     * 得到剩余冻结资金
     * 
     * @return
     */
    public long getSurplusFreezeFund() {
        return this.defaultFund - Math.abs(this.totalBusinessFund);
    }

    @Override
    public TradeEntrust clone() {
        TradeEntrust back = new TradeEntrust();
        back.businessAmount = this.businessAmount;
        back.businessFund = this.businessFund;
        back.commissionFund = this.commissionFund;
        back.commissionrate = this.commissionrate;
        back.defaultAmount = this.defaultAmount;
        back.defaultFund = this.defaultFund;
        back.entrustAmount = this.entrustAmount;
        back.entrustBS = this.entrustBS;
        back.entrustNO = this.entrustNO;
        back.entrustPrice = this.entrustPrice;
        back.entrustProp = this.entrustProp;
        back.entrustStatus = this.entrustStatus;
        back.entrustTime = this.entrustTime;
        back.fundAccount = this.fundAccount;
        back.id = this.id;
        back.lastMatchTime = this.lastMatchTime;
        back.matchingSeq = this.matchingSeq;
        back.minCommission = this.minCommission;
        back.stockAccount = this.stockAccount;
        back.stockCode = this.stockCode;
        back.totalBusinessFund = this.totalBusinessFund;
        back.transactions = this.transactions;
        back.entrustTag = this.entrustTag;
        back.managementFund = this.managementFund;
        back.managementRate = this.managementRate;
        back.gainBusinessFund = this.gainBusinessFund;
        back.userId = this.userId;
        back.status = this.status;
        back.orderSn = this.orderSn;
        back.gmtCreate = this.gmtCreate;
        back.gmtModify = this.gmtModify;
        back.goodsId = this.goodsId;
        return back;
    }

    @Override
    public boolean equals(Object obj) {
        if (this.id != null && obj != null && obj instanceof TradeEntrust) {
            TradeEntrust te = (TradeEntrust)obj;
            if (te.id != null) {
                return this.id.equals(te.id);
            }
        }
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        if (this.id != null) {
            return this.id.hashCode();
        }
        return super.hashCode();
    }

    public void setEntrustAmount(Long entrustAmount) {
        this.entrustAmount = entrustAmount;
    }

    public Long getEntrustNO() {
        return entrustNO;
    }

    public void setEntrustNO(Long entrustNO) {
        this.entrustNO = entrustNO;
    }

    public String getStockAccount() {
        return stockAccount;
    }

    public void setStockAccount(String stockAccount) {
        this.stockAccount = stockAccount;
    }

    public String getFundAccount() {
        return fundAccount;
    }

    public void setFundAccount(String fundAccount) {
        this.fundAccount = fundAccount;
    }

    public String getStockCode() {
        return stockCode;
    }

    public void setStockCode(String stockCode) {
        this.stockCode = stockCode;
    }

    public String getEntrustBS() {
        return entrustBS;
    }

    public void setEntrustBS(String entrustBS) {
        this.entrustBS = entrustBS;
    }

    public Long getEntrustPrice() {
        return entrustPrice;
    }

    public void setEntrustPrice(Long entrustPrice) {
        this.entrustPrice = entrustPrice;
    }

    public Long getEntrustAmount() {
        return entrustAmount;
    }

    public Integer getEntrustStatus() {
        return entrustStatus;
    }

    public void setEntrustStatus(Integer entrustStatus) {
        this.entrustStatus = entrustStatus;
    }

    public String getEntrustProp() {
        return entrustProp;
    }

    public void setEntrustProp(String entrustProp) {
        this.entrustProp = entrustProp;
    }

    public Long getDefaultFund() {
        return defaultFund;
    }

    public void setDefaultFund(Long defaultFund) {
        this.defaultFund = defaultFund;
    }

    public Long getDefaultAmount() {
        return defaultAmount;
    }

    public void setDefaultAmount(Long defaultAmount) {
        this.defaultAmount = defaultAmount;
    }

    public Long getBusinessAmount() {
        return businessAmount;
    }

    public void setBusinessAmount(Long businessAmount) {
        this.businessAmount = businessAmount;
    }

    public Long getTotalBusinessFund() {
        return totalBusinessFund;
    }

    public void setTotalBusinessFund(Long totalBusinessFund) {
        this.totalBusinessFund = totalBusinessFund;
    }

    public Long getBusinessFund() {
        return businessFund;
    }

    public void setBusinessFund(Long businessFund) {
        this.businessFund = businessFund;
    }

    public Long getCommissionFund() {
        return commissionFund;
    }

    public void setCommissionFund(Long commissionFund) {
        this.commissionFund = commissionFund;
    }

    public BigDecimal getCommissionrate() {
        return commissionrate;
    }

    public void setCommissionrate(BigDecimal commissionrate) {
        this.commissionrate = commissionrate;
    }

    public Long getMatchingSeq() {
        return matchingSeq;
    }

    public void setMatchingSeq(Long matchingSeq) {
        this.matchingSeq = matchingSeq;
    }

    public Date getEntrustTime() {
        return entrustTime;
    }

    public void setEntrustTime(Date entrustTime) {
        this.entrustTime = entrustTime;
    }

    public Date getGmtCreate() {
        return gmtCreate;
    }

    public void setGmtCreate(Date gmtCreate) {
        this.gmtCreate = gmtCreate;
    }

    public Date getGmtModify() {
        return gmtModify;
    }

    public void setGmtModify(Date gmtModify) {
        this.gmtModify = gmtModify;
    }

    public Long getMinCommission() {
        return minCommission;
    }

    public void setMinCommission(Long minCommission) {
        this.minCommission = minCommission;
    }

    public Integer getTransactions() {
        return transactions;
    }

    public void setTransactions(int transactions) {
        this.transactions = transactions;
    }

    public Date getLastMatchTime() {
        return lastMatchTime;
    }

    public void setLastMatchTime(Date lastMatchTime) {
        this.lastMatchTime = lastMatchTime;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Long getDeListingNo() {
        return deListingNo;
    }

    public void setDeListingNo(Long deListingNo) {
        this.deListingNo = deListingNo;
    }

    public Long getAmount() {
        return amount;
    }

    public void setAmount(Long amount) {
        this.amount = amount;
    }

    public Long getOldAutoEntrustNO() {
        return oldAutoEntrustNO;
    }

    public void setOldAutoEntrustNO(Long oldAutoEntrustNO) {
        this.oldAutoEntrustNO = oldAutoEntrustNO;
    }

    public String getLocale() {
        return locale;
    }

    public void setLocale(String locale) {
        this.locale = locale;
    }

    public Boolean getIsBestEntrust() {
        return isBestEntrust;
    }

    public void setIsBestEntrust(Boolean isBestEntrust) {
        this.isBestEntrust = isBestEntrust;
    }

    public Long getManagementFund() {
        return managementFund;
    }

    public void setManagementFund(Long managementFund) {
        this.managementFund = managementFund;
    }

    public Integer getManagementRate() {
        return managementRate;
    }

    public void setManagementRate(Integer managementRate) {
        this.managementRate = managementRate;
    }

    public Integer getEntrustTag() {
        return entrustTag;
    }

    public void setEntrustTag(Integer entrustTag) {
        this.entrustTag = entrustTag;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public Long getGainBusinessFund() {
        return gainBusinessFund;
    }

    public void setGainBusinessFund(Long gainBusinessFund) {
        this.gainBusinessFund = gainBusinessFund;
    }

    public Date getExpireDate() {
        return expireDate;
    }

    public void setExpireDate(Date expireDate) {
        this.expireDate = expireDate;
    }

    public String getOrderSn() {
        return orderSn;
    }

    public void setOrderSn(String orderSn) {
        this.orderSn = orderSn;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public Long getGoodsId() {
        return goodsId;
    }

    public void setGoodsId(Long goodsId) {
        this.goodsId = goodsId;
    }
}
